/**
 * NO.01 20150703 lin.xin  add wo_id_fk and so_id_fk to sub group condtion
 * NO.02 20150808 Fang.liu add median chart
 */
package com.dx.mes.service.spc.service;


import com.dx.common.table.ppt.*;
import com.dx.mes.common.dao.*;
import com.dx.mes.common.table.rtnBean.SimpleRtnBeen;
import com.dx.mes.common.transcoder.util.AppContext;
import com.dx.mes.common.transcoder.util.JacksonUtil;
import com.dx.mes.common.transcoder.util.LogUtils;
import com.dx.mes.common.transcoder.util.Util;
import com.dx.mes.service.spc.rtnBean.*;
import com.dx.mes.service.spc.tx.Xpspcchk.XpspcchkI;
import com.dx.mes.service.spc.tx.Xpspcchk.XpspcchkIA;
import com.dx.mes.service.spc.tx.Xpspcchk.XpspcchkO;
import com.dx.mes.service.spc.util.DroolsUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

import static com.dx.mes.common.bean.def.GenericDef.*;

@Service("xpspcchkService")
public class XpspcchkService implements IXpspcchkService {
    private LogUtils logUtils;
    private static final String _AND = " AND ";
    private static final int MAX_SPC_VALUE_CNT = 20;

    @Autowired
    IRetPrdInfoDao retPrdInfoDao;
    @Autowired
    ISpcBisGrpDtDao spcBisGrpDtDao;
    @Autowired
    ISpcBisGrpMainDao spcBisGrpMainDao;
    @Autowired
    ISpcBisChartMainDao spcBisChartMainDao;
    @Autowired
    ISpcRetChartInfoDao spcRetChartInfoDao;
    @Autowired
    ISpcRetChartDataDao spcRetChartDataDao;
    @Autowired
    ISpcRetChartRawDao spcRetChartRawDao;
    @Autowired
    DroolsUtil droolsUtil;

    public String subMainProc(String evt_no, String strInMsg) {
        AppContext.clear();
        AppContext.setCurrServiceName(XpspcchkService.class.getSimpleName());
        AppContext.setCurrEventNumber(evt_no);
        logUtils = new LogUtils(XpspcchkService.class);
        logUtils.info("[InTrx:" + strInMsg + "]");

        String strOutMsg = "";
        XpspcchkI inTrx = new XpspcchkI();
        XpspcchkO outTrx = new XpspcchkO();
        outTrx.setTrx_id("XPSPCCHK");
        outTrx.setType_id("O");
        try {
            inTrx = JacksonUtil.fromJson(strInMsg, XpspcchkI.class);
            SubMainProc2(inTrx, outTrx);
            if (!outTrx.getRtn_code().equals(RETURN_CODE_OK)) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            } else {
                outTrx.setRtn_code("0000000");
                outTrx.setRtn_mesg("success");
                spcRetChartDataDao.flushCurSession();
            }
        } catch (Exception ex) {
            logUtils.info(ex.toString());
            outTrx.setRtn_code("0000001");
            outTrx.setRtn_mesg(Util.stackTraceToString(ex));
        } finally {
            strOutMsg = JacksonUtil.toJSONStr(outTrx);
            logUtils.info("[OutTrx:" + strOutMsg + "]");
        }
        return strOutMsg;
    }

    /**
     * @param inTrx
     * @param xpspcchkO
     * @param xpsiqcinI
     * @return
     */
    public void SubMainProc2(XpspcchkI inTrx, XpspcchkO outTrx) {
        List<XpspcchkIA> iaryList = inTrx.getIary();
        SimpleRtnBeen rtnBeen = new SimpleRtnBeen(_NORMAL);
        String gszMsgBuf = "";
        String colTyp = "2";//写死为2
        String pToolId = inTrx.getP_tool_id();
        String evtUsr = inTrx.getEvt_usr();

        //改成tool
        rtnBeen = setSpcItem(inTrx);
        if (_NORMAL != rtnBeen.getlRc()) {
            gszMsgBuf = rtnBeen.getMsgBuf();
            outTrx.setRtn_mesg(gszMsgBuf);
            return;
        }
            rtnBeen = normalSpcProc(iaryList, colTyp, pToolId,evtUsr, inTrx, outTrx, rtnBeen);
            if (rtnBeen.getlRc() != _NORMAL) {
                gszMsgBuf = rtnBeen.getMsgBuf();
                outTrx.setRtn_mesg(gszMsgBuf);
                return;
            }
        outTrx.setRtn_code(RETURN_CODE_OK);
        outTrx.setRtn_mesg(RETURN_MESG_OK);
        return;
    }

    /*private SimpleRtnBeen cdpcSpcProc(List<XpspcchkIA> iaryList, String colTyp, String mdl_id, String p_tool_id, String p_recipe_id,
                                      String p_path_id, String p_path_ver, String p_ope_no, String p_ope_id, String p_ope_ver, String p_proc_id,
                                      String wo_id, String so_id, String cus_id, String prd_seq_id, String evt_usr, XpspcchkI inTrx,XpspcchkO outTrx, SimpleRtnBeen rtnBeen) {
        SpcItem spcItem = (SpcItem) rtnBeen.getObj();
        Double thickness = inTrx.getTarget_thickness();
        //String thicknessType = inTrx.getThickness_type();
        String gszMsgBuf = "";

        for (int jx = 0; !spcItem.getPrdSeqList().isEmpty() && jx < spcItem.getPrdSeqList().get(0).getData_group_cnt(); jx++) {
            DataGroupItem dataGroupItem = spcItem.getPrdSeqList().get(0).getDataGroupList().get(jx);
            String dataGroup = dataGroupItem.getData_group();

            List<ValueItem> valueItemList = dataGroupItem.getData_valueList();
            List<Double> valueList = new ArrayList<Double>();
            for (ValueItem valueItem : valueItemList) {
                valueList.add(valueItem.getData_value());
            }

            Double chartValue = Double.valueOf(iaryList.get(jx).getData_value());

            *//**
             * find chart that satisfying the conditions containing data_group and target
             *	and chart_ack_flg = ?  ,thicknessType js中判断
             *//*
            String hql = "FROM Spc_ret_chart_info where col_typ_fk = ? and data_group_fk = ? and chart_target = ?  and chart_typ_fk in ('01','10','20','30','40','50')";
            List<Spc_ret_chart_info> mainSpcRetChartInfoList = spcRetChartInfoDao.list(hql, 2, dataGroup, thickness);
            //根据ret_wo的目标厚度 = 管制图的标准线 判断是否有该chart图
            if (mainSpcRetChartInfoList.isEmpty()) {
                gszMsgBuf = "没有找到对应标准线为[" + thickness + "]的管制图!";
                return new SimpleRtnBeen(3003602L, gszMsgBuf);
            }

            for (Spc_ret_chart_info mainSpcRetChartInfo : mainSpcRetChartInfoList) {

                *//**
                 * list main and slave chart by grp_no ,chart_no
                 *//*
                hql = "FROM Spc_ret_chart_info where col_typ_fk = ? and grp_no_fk = ? and chart_no_fk = ? ";

                List<Spc_ret_chart_info> spcRetChartInfoList = spcRetChartInfoDao.list(hql, 2, mainSpcRetChartInfo.getId()
                        .getGrp_no_fk(), mainSpcRetChartInfo.getId().getChart_no_fk());

                reportSpcProc(colTyp, mdl_id, p_tool_id, p_recipe_id, p_path_id, p_ope_no, p_ope_id, p_proc_id, wo_id, so_id,
                        cus_id, prd_seq_id, evt_usr, "00", valueItemList, valueList, chartValue, spcRetChartInfoList, inTrx,outTrx,null,"");
            }

        }
        return new SimpleRtnBeen(_NORMAL);
    }*/

    private SimpleRtnBeen normalSpcProc(List<XpspcchkIA> iaryList, String colTyp, String pToolId,
                                       String evtUsr, XpspcchkI inTrx, XpspcchkO outTrx, SimpleRtnBeen rtnBeen) {
        String gszMsgBuf = "";
        SpcItem spcItem = (SpcItem) rtnBeen.getObj();
        StringBuffer sqlBuffer = new StringBuffer();
        sqlBuffer.append("FROM Spc_bis_grp_dt where col_typ_fk= ? ");
        sqlBuffer.append(_AND).append("( tool_id_fk=? OR tool_id_fk='*') ");
      /*  sqlBuffer.append(_AND).append("( mdl_id_fk=? OR mdl_id_fk='*') ");
        sqlBuffer.append(_AND).append("( recipe_id_fk=? OR recipe_id_fk='*') ");
        sqlBuffer.append(_AND).append("( path_id_fk=? OR path_id_fk='*') ");
        sqlBuffer.append(_AND).append("( path_ver_fk=? OR path_ver_fk='*') ");
        sqlBuffer.append(_AND).append("( ope_no_fk=? OR ope_no_fk='*') ");
        sqlBuffer.append(_AND).append("( ope_id_fk=? OR ope_id_fk='*') ");
        sqlBuffer.append(_AND).append("( ope_ver_fk=? OR ope_ver_fk='*') ");
        sqlBuffer.append(_AND).append("( proc_id=? OR proc_id='*') ");
        sqlBuffer.append(_AND).append("( wo_id_fk=? OR wo_id_fk='*') ");
        sqlBuffer.append(_AND).append("( cus_id_fk=? OR cus_id_fk='*') ");*/
        sqlBuffer.append(" ORDER BY col_typ_fk,grp_no_fk ");

        List<Spc_bis_grp_dt> spcBisGrpDtList = spcBisGrpDtDao.list(sqlBuffer.toString(), colTyp, pToolId);

        if (spcBisGrpDtList.isEmpty()) {
            gszMsgBuf = "not found Spc_bis_gr_dt";
            outTrx.setRtn_mesg(gszMsgBuf);
            outTrx.setRtn_code(RETURN_CODE_UNKNOWN);
            return new SimpleRtnBeen(E_FSPBOXCHG_OLD_BOX_ID_NULL, gszMsgBuf);
        }
        for (int ix = 0; ix < spcBisGrpDtList.size(); ix++) {
            //不可以出现一个点进入一张chart两次的情况
            if (ix > 0) {
                if (spcBisGrpDtList.get(ix).getId().getGrp_no_fk().equals(spcBisGrpDtList.get(ix - 1).getId().getGrp_no_fk())
                        && spcBisGrpDtList.get(ix).getId().getCol_typ_fk()
                        .equals(spcBisGrpDtList.get(ix - 1).getId().getCol_typ_fk())) {
                    continue;
                }
            }
            Spc_bis_grp_mainId spcBisGrpMainId = new Spc_bis_grp_mainId();

            String grpNo = spcBisGrpDtList.get(ix).getId().getGrp_no_fk();
            String subGrpNo = spcBisGrpDtList.get(ix).getId().getSub_grp_no();

            spcBisGrpMainId.setCol_typ(colTyp);
            spcBisGrpMainId.setGrp_no(grpNo);
                Spc_bis_grp_main spcBisGrpMain = spcBisGrpMainDao.get(spcBisGrpMainId);
            if (spcBisGrpMain == null) {
                gszMsgBuf = "not found spc_bis_grp_main";
                outTrx.setRtn_mesg(gszMsgBuf);
                outTrx.setRtn_code(RETURN_CODE_UNKNOWN);
                return new SimpleRtnBeen(E_FSPBOXCHG_OLD_BOX_ID_NULL, gszMsgBuf);
            }

             for (int jx = 0; !spcItem.getToolIdItemList().isEmpty() && jx < spcItem.getToolIdItemList().get(0).getData_group_cnt(); jx++) {

                DataGroupItem dataGroupItem = spcItem.getToolIdItemList().get(0).getDataGroupList().get(jx);
                String dataGroup = dataGroupItem.getData_group();

                sqlBuffer.setLength(0);
                sqlBuffer.append(" FROM Spc_bis_chart_main WHERE col_typ_fk= ?");
                sqlBuffer.append(" and grp_no_fk= ?");
                sqlBuffer.append(" and data_group_fk= ?");

                List<Spc_bis_chart_main> spcBisChartMainList = spcBisChartMainDao.list(sqlBuffer.toString(), colTyp,
                        grpNo, dataGroup);
                if (spcBisChartMainList.isEmpty()) {
                    continue;
                }
                for (Spc_bis_chart_main spcBisChartMain : spcBisChartMainList) {
                    String chartNo = spcBisChartMain.getId().getChart_no();

                    String chartName = spcBisChartMain.getChart_name();
                    Integer sampleSize = spcBisChartMain.getSample_size();//样本数
                    Integer maxChartPoint = spcBisChartMain.getMax_chart_point();//管制图最大点数

                    List<Double> valueList = new ArrayList<Double>();
                    List<ValueItem> valueItemList = new ArrayList<ValueItem>();

                        valueItemList = dataGroupItem.getData_valueList();
                        valueList = new ArrayList<Double>();
                        for (ValueItem valueItem : valueItemList) {
                            valueList.add(valueItem.getData_value());
                        }


                    Double chartValue = Double.valueOf(iaryList.get(jx).getData_value());

                    String hql = "FROM Spc_ret_chart_info where col_typ_fk = ? AND grp_no_fk = ? AND chart_no_fk = ? ";
                    List<Spc_ret_chart_info> spcRetChartInfoList = spcRetChartInfoDao.list(hql, colTyp, grpNo, chartNo);
                    if (spcRetChartInfoList.isEmpty()) {
                        logUtils.error("not found Record in spc_bis_chart_info");
                        continue;
                    }
                    reportSpcProc(colTyp,pToolId,
                            evtUsr, subGrpNo, valueItemList, valueList, chartValue, spcRetChartInfoList, inTrx,outTrx,maxChartPoint,chartName);

                }

            }
        }
        return new SimpleRtnBeen(RETURN_CODE_OK);
    }

    private  void reportSpcProc(String colTyp, String p_tool_id,
                               String evt_usr, String sub_grp_no, List<ValueItem> valueItemList, List<Double> valueList, Double chartValue,
                               List<Spc_ret_chart_info> spcRetChartInfoList, XpspcchkI inTrx,XpspcchkO outTrx,Integer maxChartPoint,String chartName) {
        String gszMsgBuf = "";
        Timestamp proc_timestamp = Util.getCurrentTimestamp(); //NO.03
        //除了tool_Id其余赋空值
        String  mdl_id = "";
        String p_recipe_id = "";
        String p_path_id = "";
        String p_ope_no = "";
        String p_ope_id = "";
        String p_proc_id = "";
        String wo_id = "";
        String so_id = "";
        String cus_id = "";
        String prd_seq_id = "";
        //chartNo, dataValue, chartValue,

        for (Spc_ret_chart_info spcRetChartInfo : spcRetChartInfoList) {
            Spc_ret_chart_infoId spcRetChartInfoId = spcRetChartInfo.getId();
            String grpNo = spcRetChartInfoId.getGrp_no_fk();
            String chartNo = spcRetChartInfoId.getChart_no_fk();
            String chartTyp = spcRetChartInfoId.getChart_typ_fk();
            if (chartTyp.equals(SPC_CHART_TYPE_SINGLE)) {
                //多点只进 mean chart ,不进 single chart
                if (valueList.size() != 1) {
                    continue;
                }
                chartValue = chartValue;
            } else if (chartTyp.equals(SPC_CHART_TYPE_MOVING_RANGE)) { //单值 移动极差图
                //多点只进 mean chart ,不进 single chart
                if (valueList.size() != 1) {
                    continue;
                }
                //get previous chart value : single chart's (main chart) chart_value
                String mainSpcRetChartInfoSql = "FROM Spc_ret_chart_info where col_typ_fk =? and grp_no_fk = ? and chart_no_fk = ? and chart_typ_fk = ?";
                Spc_ret_chart_info mainSpcRetChartInfo = spcRetChartInfoDao.uniqueResult(mainSpcRetChartInfoSql,
                        spcRetChartInfoId.getCol_typ_fk(), spcRetChartInfoId.getGrp_no_fk(), spcRetChartInfoId.getChart_no_fk(),
                        SPC_CHART_TYPE_SINGLE);
                Double pvChartvalue = mainSpcRetChartInfo.getChart_l_value19();

                //第一个点不计入Moving Range Chart
                if (pvChartvalue == null) {
                    continue;
                    //							pvChartvalue = Double.valueOf("0");
                }
                chartValue = Math.abs(chartValue - pvChartvalue);//参数绝对值
            } else if (chartTyp.equals(SPC_CHART_TYPE_MEAN)) {
                //一个点不允许进 mean chart
                if (valueList.size() < 2) {
                    continue;
                }
                chartValue = getAveArray(valueList); //平均值
            } else if (chartTyp.equals(SPC_CHART_TYPE_RANGE)) {//极差
                //一个点不允许进 mean chart
                if (valueList.size() < 2) {
                    continue;
                }
                Double maxValue = getMaxArray(valueList);
                Double minValue = getMinArray(valueList);
                chartValue = maxValue - minValue; //极差
            } else if (chartTyp.equals(SPC_CHART_TYPE_SIGMA)) {//标准差
                //一个点不允许进 mean chart
                if (valueList.size() < 2) {
                    continue;
                }
                chartValue = getSigmaArray(valueList);//估计标准差 任一过程参数的平均值的分布或离散程度。
            } else if (chartTyp.equals(SPC_CHART_TYPE_COUNT)) {
            } else if (chartTyp.equals(SPC_CHART_TYPE_MEDIAN)) { //NO.02 中位数
                if (valueList.size() < 2) {
                    continue;
                }
                chartValue = getMedianArray(valueList);
            } else if (chartTyp.equals(SPC_CHART_TYPE_MRANGE)) { //NO.02 移动极差图
                if (valueList.size() < 2) {
                    continue;
                }
                Double maxValue = getMaxArray(valueList);
                Double minValue = getMinArray(valueList);
                chartValue = maxValue - minValue;
            } else if (chartTyp.equals(SPC_CHART_TYPE_UNIFM)){//（最大点减最小点）/(最大点加最小点)
                if(valueList.size() < 2){
                    continue;
                }
                Double maxValue = getMaxArray(valueList);
                Double minValue = getMinArray(valueList);
                chartValue  = (maxValue - minValue)/(maxValue + minValue);
            } else {
                chartValue = chartValue;
            }

            if (chartTyp.equals(SPC_CHART_TYPE_SINGLE) || chartTyp.equals(SPC_CHART_TYPE_MEAN)
                    || chartTyp.equals(SPC_CHART_TYPE_P) || chartTyp.equals(SPC_CHART_TYPE_NP) || chartTyp.equals(SPC_CHART_TYPE_C)) {
                //不合格品率图                                         //不合格品数图                         //不合格数图
                spcRetChartInfo = ruleCalucate(spcRetChartInfo, chartValue); //NO.03
            }

            //count chart process, their
            if (chartTyp.equals(SPC_CHART_TYPE_P) || chartTyp.equals(SPC_CHART_TYPE_NP) || chartTyp.equals(SPC_CHART_TYPE_C)) {
                //不合格率图                            //不合格数图                             //不合格数图
                for (int x = 0; x < valueItemList.size(); x++) {
                    Double sigma = checkSpcRetChartRawProc(spcRetChartInfo);
                    chartValue = valueItemList.get(x).getData_value();
                    final long dInputTime = System.currentTimeMillis();

                    addSpcRetChartDataProc(colTyp, mdl_id, p_tool_id, p_recipe_id, p_path_id, p_ope_no, p_ope_id, p_proc_id,
                            so_id, wo_id, cus_id, prd_seq_id, evt_usr, grpNo, sub_grp_no, valueList, chartNo, chartValue,
                            spcRetChartInfo, chartTyp, dInputTime, inTrx,sigma);
                }

            } else {
                //如果设置了管制图点数,则需要check 对应的管制图是否已满
               /* if(maxChartPoint != null){
                    checkSpcRetChartList(spcRetChartInfo,maxChartPoint);
                }*/
                Double sigma = null;
                //sigma = checkSpcRetChartRawProc(spcRetChartInfo);
                final long dInputTime = System.currentTimeMillis();

                    addSpcRetChartDataProc(colTyp, mdl_id, p_tool_id, p_recipe_id, p_path_id, p_ope_no, p_ope_id, p_proc_id, wo_id,
                        so_id, cus_id, prd_seq_id, evt_usr, grpNo, sub_grp_no, valueList, chartNo, chartValue, spcRetChartInfo,
                        chartTyp, dInputTime, inTrx,sigma);

                if (chartTyp.equals(SPC_CHART_TYPE_MEAN) || chartTyp.equals(SPC_CHART_TYPE_MEDIAN)) {
                    //平均数                                   //中位数
                    addSpcRetChartRawProc(colTyp, prd_seq_id, grpNo, sub_grp_no, proc_timestamp, valueItemList, chartNo,
                            dInputTime);
                }
            }
        }
    }

    //check对应chart图的总点数
    public void checkSpcRetChartList(Spc_ret_chart_info spcRetChartInfo,Integer maxChartPoint){
        String colTyp = spcRetChartInfo.getId().getCol_typ_fk();
        String grpNo  = spcRetChartInfo.getId().getGrp_no_fk();
        String chartNo = spcRetChartInfo.getId().getChart_no_fk();
        String chart_typ = spcRetChartInfo.getId().getChart_typ_fk();

        List<Spc_ret_chart_data> spc_ret_chart_data_list = new ArrayList<>();
        String hql ="FROM Spc_ret_chart_data WHERE 1=1";
        if (colTyp != null) {
            hql = hql +" and col_typ_fk='" +colTyp +"'";
        }
        if (grpNo != null) {
            hql = hql +" and grp_no_fk='" +grpNo +"'";
        }
        if (chartNo != null) {
            hql = hql +" and chart_no_fk='" +chartNo +"'";
        }
        if (chart_typ != null) {
            hql = hql +" and chart_typ_fk='" +chart_typ +"'";
        }
        hql = hql + " order by input_time_d desc";
        //降序数据
        spc_ret_chart_data_list = spcRetChartDataDao.find(hql);

        Integer size = spc_ret_chart_data_list.size();
        //如果图内点数超过了设置的最大点数，则删除不在范围内的旧数据
        if(size >= maxChartPoint){
            Spc_ret_chart_data spc_ret_chart_data = spc_ret_chart_data_list.get(maxChartPoint-1);
            Long inputTime = spc_ret_chart_data.getId().getInput_time_d();
            String hql2 = "From Spc_ret_chart_data WHERE 1=1";
            if (colTyp != null) {
                hql2 = hql2 +" and col_typ_fk='" +colTyp +"'";
            }
            if (grpNo != null) {
                hql2 = hql2 +" and grp_no_fk='" +grpNo +"'";
            }
            if (chartNo != null) {
                hql2 = hql2 +" and chart_no_fk='" +chartNo +"'";
            }
            if (chart_typ != null) {
                hql2 = hql2 +" and chart_typ_fk='" +chart_typ +"'";
            }
                hql2 = hql2+ " and input_time_d <= "+ inputTime +"";
            List<Spc_ret_chart_data> spc_ret_chart_dataList = spcRetChartDataDao.find(hql2);
            spcRetChartDataDao.deleteAll(spc_ret_chart_dataList);

            //同时删除ret_chart_raw_data原始数据
            //子管控组号码
            String subGrpNoFk = spc_ret_chart_data_list.get(0).getSub_grp_no_fk();
            String hql3 = "From Spc_ret_chart_raw WHERE 1=1";
            if (colTyp != null) {
                hql3 = hql3 +" and col_typ_fk='" + colTyp +"'";
            }
            if (grpNo != null) {
                hql3 = hql3 +" and grp_no_fk='" + grpNo +"'";
            }
            if (subGrpNoFk != null) {
                hql3 = hql3 +" and sub_grp_no='" + subGrpNoFk +"'";
            }
            if (chartNo != null) {
                hql3 = hql3 +" and chart_no_fk='" + chartNo +"'";
            }
            hql3 = hql3 +"and proc_time_d <= " + inputTime +"";
            List<Spc_ret_chart_raw> spc_ret_chart_raws = spcRetChartRawDao.find(hql3);
            if(spc_ret_chart_raws.size() != 0){
                spcRetChartRawDao.deleteAll(spc_ret_chart_raws);
            }
        }
        return;
    }


    //check指定管制图的点数满25则计算sigma
    public Double checkSpcRetChartRawProc(Spc_ret_chart_info spcRetChartInfo){
        String colTyp = spcRetChartInfo.getId().getCol_typ_fk();
        String grpNo  = spcRetChartInfo.getId().getGrp_no_fk();
        String chartNo = spcRetChartInfo.getId().getChart_no_fk();
        String chart_typ = spcRetChartInfo.getId().getChart_typ_fk();

        List<Spc_ret_chart_data> spc_ret_chart_data_list = new ArrayList<>();
        String hql ="FROM Spc_ret_chart_data WHERE 1=1";
        if (colTyp != null) {
            hql = hql +" and col_typ_fk='" +colTyp +"'";
        }
        if (grpNo != null) {
            hql = hql +" and grp_no_fk='" +grpNo +"'";
        }
        if (chartNo != null) {
            hql = hql +" and chart_no_fk='" +chartNo +"'";
        }
        if (chart_typ != null) {
            hql = hql +" and chart_typ_fk='" +chart_typ +"'";
        }
        hql = hql + " order by input_time_d asc";
        spc_ret_chart_data_list = spcRetChartDataDao.find(hql);
        Integer size = spc_ret_chart_data_list.size();

        if(chart_typ.equals(SPC_CHART_TYPE_MEAN)){
            if(size >= 25){
                //计算sigma
                List<Spc_ret_chart_data> chartDataList = new ArrayList<Spc_ret_chart_data>();
                for (int i = 1 ; i < 26 ; i++){
                    Spc_ret_chart_data spc_ret_chart_data= spc_ret_chart_data_list.get(size-i);
                    chartDataList.add(spc_ret_chart_data);
                }
                Integer totalSampleCnt = 25;
                Double totalSampleValue = 0.0;
                Double avgSum = 0.0;
                for(int i = 0; i < chartDataList.size(); i++){
                    totalSampleValue += chartDataList.get(i).getChart_value();
                }
                //25点平均值
                Double mean = totalSampleValue / totalSampleCnt;
                //计算方差
                for (int i = 0 ;i < chartDataList.size(); i++){
                    Double chartValue = chartDataList.get(i).getChart_value();
                    avgSum += (chartValue - mean)*(chartValue - mean);
                }
                //计算sigma(标准差）
                Double sigma = Math.sqrt(avgSum/25);
                return sigma;
            }
        }

        return null;
    }

    private void addSpcRetChartRawProc(String colTyp, String prd_seq_id, String grpNo, String sub_grp_no,
                                       Timestamp proc_timestamp, List<ValueItem> valueItemList, String chartNo, long dInputTime) {
        for (int i = 0; i < valueItemList.size(); i++) {
            ValueItem valueItem = valueItemList.get(i);

            Spc_ret_chart_raw spc_ret_chart_raw = new Spc_ret_chart_raw();
            Spc_ret_chart_rawId spc_ret_chart_rawId = new Spc_ret_chart_rawId();
            spc_ret_chart_rawId.setCol_typ_fk(colTyp);
            spc_ret_chart_rawId.setGrp_no_fk(grpNo);
            spc_ret_chart_rawId.setChart_no_fk(chartNo);
            spc_ret_chart_rawId.setProc_time_d(dInputTime);
            spc_ret_chart_rawId.setPrd_value_seq(i);
            spc_ret_chart_rawId.setSub_grp_no(sub_grp_no);
            spc_ret_chart_raw.setId(spc_ret_chart_rawId);
            spc_ret_chart_raw.setProc_timestamp(proc_timestamp);
            spc_ret_chart_raw.setPrd_seq_id_fk(prd_seq_id);
            spc_ret_chart_raw.setData_group_seq_fk(valueItem.getData_group_seq());
            spc_ret_chart_raw.setPrd_raw_value(valueItem.getData_value());

            spcRetChartRawDao.save(spc_ret_chart_raw);
        }
    }

    private void addSpcRetChartDataProc(String colTyp, String mdl_id, String p_tool_id, String p_recipe_id, String p_path_id,
                                        String p_ope_no, String p_ope_id, String p_proc_id, String wo_id, String so_id, String cus_id, String prd_seq_id,
                                        String evt_usr, String grpNo, String sub_grp_no, List<Double> valueList, String chartNo, Double chartValue,
                                        Spc_ret_chart_info spcRetChartInfo, String chart_typ, long dInputTime, XpspcchkI inTrx,Double sigma) {

        String lot_id = inTrx.getLot_id_fk();
        String m_tool_id = inTrx.getM_tool_id();
        String m_recipe_id = inTrx.getM_recipe_id();
        String todoSpace = " ";

        Spc_ret_chart_data spc_ret_chart_data = new Spc_ret_chart_data();
        Spc_ret_chart_dataId spc_ret_chart_dataId = new Spc_ret_chart_dataId();
        spc_ret_chart_dataId.setCol_typ_fk(colTyp);
        spc_ret_chart_dataId.setGrp_no_fk(grpNo);
        spc_ret_chart_dataId.setChart_no_fk(chartNo);
        spc_ret_chart_dataId.setChart_typ_fk(chart_typ);
        spc_ret_chart_dataId.setInput_time_d(dInputTime);
        spc_ret_chart_data.setId(spc_ret_chart_dataId);
        spc_ret_chart_data.setInput_timestamp(Util.getCurrentTimestamp());
        spc_ret_chart_data.setProc_timestamp(inTrx.getEvt_timestamp());
        spc_ret_chart_data.setSub_grp_no_fk(sub_grp_no);
        spc_ret_chart_data.setEvt_usr(evt_usr);
        spc_ret_chart_data.setPrd_seq_id_fk(prd_seq_id);
        spc_ret_chart_data.setExd_flg(todoSpace);
        spc_ret_chart_data.setChart_value(chartValue);
        spc_ret_chart_data.setSample_size_fk(valueList.size());
        spc_ret_chart_data.setChart_spec_rlt_fk(spcRetChartInfo.getChart_spec_rlt());
        spc_ret_chart_data.setChart_rule_1_rlt_fk(spcRetChartInfo.getChart_rule_1_rlt());
        spc_ret_chart_data.setChart_rule_2_rlt_fk(spcRetChartInfo.getChart_rule_2_rlt());
        spc_ret_chart_data.setOoc_ocap_fk(todoSpace);
        spc_ret_chart_data.setOos_ocap_fk(todoSpace);
        spc_ret_chart_data.setChart_total_action_fk(spcRetChartInfo.getChart_total_action());
        spc_ret_chart_data.setChart_detail_action_fk(todoSpace);
        spc_ret_chart_data.setChart_usl_fk(spcRetChartInfo.getChart_usl()); //NO.03
        spc_ret_chart_data.setChart_lsl_fk(spcRetChartInfo.getChart_lsl()); //NO.03

        spc_ret_chart_data.setChart_mean_fk(spcRetChartInfo.getChart_mean()); //NO.03
        if(chart_typ.equals(SPC_CHART_TYPE_MEAN)){
            if (sigma == null) {
                spc_ret_chart_data.setChart_ucl_fk(spcRetChartInfo.getChart_ucl()); //NO.03
                spc_ret_chart_data.setChart_lcl_fk(spcRetChartInfo.getChart_lcl()); //NO.03
            }else {
                spc_ret_chart_data.setChart_ucl_fk(spcRetChartInfo.getChart_mean() + 3*sigma);
                spc_ret_chart_data.setChart_lcl_fk(spcRetChartInfo.getChart_mean() - 3*sigma);
            }
        }else{
            //除了MEAN图其他都暂时设置为设定的控制线
            spc_ret_chart_data.setChart_ucl_fk(spcRetChartInfo.getChart_ucl()); //NO.03
            spc_ret_chart_data.setChart_lcl_fk(spcRetChartInfo.getChart_lcl()); //NO.03
        }

        spc_ret_chart_data.setChart_uwl_fk(spcRetChartInfo.getChart_uwl()); //NO.03
        spc_ret_chart_data.setChart_lwl_fk(spcRetChartInfo.getChart_lwl()); //NO.03

        spc_ret_chart_data.setMdl_id_fk(mdl_id);
        spc_ret_chart_data.setP_tool_id_fk(p_tool_id);
        spc_ret_chart_data.setP_recipe_id_fk(p_recipe_id);
        spc_ret_chart_data.setP_path_id_fk(p_path_id);
        spc_ret_chart_data.setP_ope_no_fk(p_ope_no);
        spc_ret_chart_data.setP_ope_id_fk(p_ope_id);
        spc_ret_chart_data.setP_proc_id(p_proc_id);
        spc_ret_chart_data.setM_tool_id_fk(m_tool_id);
        spc_ret_chart_data.setM_recipe_id_fk(m_recipe_id);
        spc_ret_chart_data.setLot_id_fk(lot_id);
        spc_ret_chart_data.setCus_id_fk(cus_id);
        spc_ret_chart_data.setWo_id_fk(wo_id);
        spc_ret_chart_data.setSo_id_fk(so_id);
        spcRetChartDataDao.save(spc_ret_chart_data);

    }

    public String getRuleResult(char rule, boolean isBreakRule, String chart_rlt) {
        if (rule == 'H') {
            if (isBreakRule == true) {
                return chart_rlt + "H";
            } else {
                return chart_rlt + "N";
            }
        } else if (rule == 'W') {
            if (isBreakRule == true) {
                return chart_rlt + "W";
            } else {
                return chart_rlt + "N";
            }
        }
        return chart_rlt + "N";
    }

    public boolean getHoldFlg(SpcRuleRltObj spcRuleObj, boolean isBreakRule) {
        if (spcRuleObj.isHold_flg() == true || isBreakRule == true) {
            return true;
        }
        return false;
    }

    public long sendAlarm(String message) {

        return _NORMAL;
    }

    public SimpleRtnBeen setSpcItem(XpspcchkI inTrx) {
        SpcItem spcItem = new SpcItem();
        ToolIdItem toolIdItem = new ToolIdItem();
        //PrdSeqItem prdSeqItem = new PrdSeqItem();
        //List<PrdSeqItem> prdSeqList = new ArrayList<PrdSeqItem>();
        List<ToolIdItem> toolIdItems = new ArrayList<ToolIdItem>();
        List<DataGroupItem> dataGroupList = new ArrayList<DataGroupItem>();
        List<XpspcchkIA> iaryList = inTrx.getIary();
        List<String> dgStringList = new ArrayList<String>();
        String data_group;
        for (XpspcchkIA iary : iaryList) {
            data_group = iary.getData_group();
            if (dataGroupList.size() == 0) {
                DataGroupItem dataGroupItem = new DataGroupItem();
                dataGroupItem.setData_group(data_group);
                List<ValueItem> valueItemList = new ArrayList<ValueItem>();
                ValueItem firstValueItem = new ValueItem();
                firstValueItem.setData_group_seq(iary.getData_group_seq());
                firstValueItem.setData_value(Double.valueOf(iary.getData_value()));
                valueItemList.add(firstValueItem);
                for (int i = 1; i < iaryList.size(); i++) {
                    if (iaryList.get(i).getData_group().equals(data_group)) {
                        //valueList.add(Double.valueOf( iaryList.get(i).getData_value() ));
                        ValueItem valueItem = new ValueItem();
                        valueItem.setData_group_seq(iaryList.get(i).getData_group_seq());
                        valueItem.setData_value(Double.valueOf(iaryList.get(i).getData_value()));
                        valueItemList.add(valueItem);
                    }
                }
                dataGroupItem.setData_valueList(valueItemList);
                dataGroupItem.setValue_cnt(valueItemList.size());

                dataGroupList.add(dataGroupItem);
                dgStringList.add(data_group);
            } else {
                boolean isExist = false;
                for (String dgString : dgStringList) {
                    if (dgString.equals(data_group)) {
                        isExist = true;
                        break;
                    }
                }
                if (isExist == true) {
                    continue;
                }
                DataGroupItem dataGroupItem = new DataGroupItem();
                dataGroupItem.setData_group(data_group);
                List<ValueItem> valueItemList = new ArrayList<ValueItem>();
                for (int i = 1; i < iaryList.size(); i++) {
                    if (iaryList.get(i).getData_group().equals(data_group)) {
                        //valueList.add(Double.valueOf( iaryList.get(i).getData_value() ));
                        ValueItem valueItem = new ValueItem();
                        valueItem.setData_group_seq(iaryList.get(i).getData_group_seq());
                        valueItem.setData_value(Double.valueOf(iaryList.get(i).getData_value()));
                        valueItemList.add(valueItem);
                    }
                }
                dataGroupItem.setData_valueList(valueItemList);
                dataGroupItem.setValue_cnt(valueItemList.size());
                dataGroupList.add(dataGroupItem);
                dgStringList.add(data_group);
            }
        }
        toolIdItem.setData_group_cnt(dataGroupList.size());
        toolIdItem.setDataGroupList(dataGroupList);
        toolIdItems.add(toolIdItem);
        //spcItem.setPrdSeqList(prdSeqList);
        spcItem.setToolIdItemList(toolIdItems);
        spcItem.setPrd_seq_cnt(1);
        return new SimpleRtnBeen(_NORMAL, spcItem);
    }

    public Double getMaxArray(List<Double> valueList) {
        Double maxValue = valueList.get(0);
        for (int i = 0; i < valueList.size(); i++) {
            if (valueList.get(i) > maxValue) {
                maxValue = valueList.get(i);
            }
        }
        return maxValue;
    }

    public Double getMinArray(List<Double> valueList) {
        Double minValue = valueList.get(0);
        for (int i = 0; i < valueList.size(); i++) {
            if (valueList.get(i) < minValue) {
                minValue = valueList.get(i);
            }
        }
        return minValue;
    }

    public Double getAveArray(List<Double> valueList) {
        Double valueSum = Double.valueOf(0);
        for (Double d : valueList) {
            valueSum = valueSum + d;
        }
        return (valueSum / valueList.size());
    }

    public Double getSigmaArray(List<Double> valueList) {
        int cnt = valueList.size();
        Double average = getAveArray(valueList);//平均值
        double temp = 0;
        for (int i = 0; i < cnt; i++) {
            temp = temp + Math.pow((valueList.get(i) - average), 2);//pow(X,y)就是计算X的Y次方
        }
        temp = temp / (cnt - 1);

        return Math.sqrt(temp);//平方根

    }

    public boolean isEmpty(Double d) {
        return d == null || d == 0 ? true : false;
    }

    public Spc_ret_chart_info ruleCalucate(Spc_ret_chart_info spcRetChartInfo, Double chartValue) {
        String chart_rule1_rlt = "";
        Double value1 = spcRetChartInfo.getChart_l_value02();
        Double value2 = spcRetChartInfo.getChart_l_value03();
        Double value3 = spcRetChartInfo.getChart_l_value04();
        Double value4 = spcRetChartInfo.getChart_l_value05();
        Double value5 = spcRetChartInfo.getChart_l_value06();
        Double value6 = spcRetChartInfo.getChart_l_value07();
        Double value7 = spcRetChartInfo.getChart_l_value08();
        Double value8 = spcRetChartInfo.getChart_l_value09();
        Double value9 = spcRetChartInfo.getChart_l_value10();
        Double value10 = spcRetChartInfo.getChart_l_value11();
        Double value11 = spcRetChartInfo.getChart_l_value12();
        Double value12 = spcRetChartInfo.getChart_l_value13();
        Double value13 = spcRetChartInfo.getChart_l_value14();
        Double value14 = spcRetChartInfo.getChart_l_value15();
        Double value15 = spcRetChartInfo.getChart_l_value16();
        Double value16 = spcRetChartInfo.getChart_l_value17();
        Double value17 = spcRetChartInfo.getChart_l_value18();
        Double value18 = spcRetChartInfo.getChart_l_value19();
        Double value19 = spcRetChartInfo.getChart_l_value20();
        Double value20 = chartValue;

        Double[] values = new Double[]{value1, value2, value3, value4, value5, value6, value7, value8, value9, value10,
                value11, value12, value13, value14, value15, value16, value17, value18, value19, value20};

        spcRetChartInfo.setChart_l_value01(value1);
        spcRetChartInfo.setChart_l_value02(value2);
        spcRetChartInfo.setChart_l_value03(value3);
        spcRetChartInfo.setChart_l_value04(value4);
        spcRetChartInfo.setChart_l_value05(value5);
        spcRetChartInfo.setChart_l_value06(value6);
        spcRetChartInfo.setChart_l_value07(value7);
        spcRetChartInfo.setChart_l_value08(value8);
        spcRetChartInfo.setChart_l_value09(value9);
        spcRetChartInfo.setChart_l_value10(value10);
        spcRetChartInfo.setChart_l_value11(value11);
        spcRetChartInfo.setChart_l_value12(value12);
        spcRetChartInfo.setChart_l_value13(value13);
        spcRetChartInfo.setChart_l_value14(value14);
        spcRetChartInfo.setChart_l_value15(value15);
        spcRetChartInfo.setChart_l_value16(value16);
        spcRetChartInfo.setChart_l_value17(value17);
        spcRetChartInfo.setChart_l_value18(value18);
        spcRetChartInfo.setChart_l_value19(value19);
        spcRetChartInfo.setChart_l_value20(value20);

        Double usl = spcRetChartInfo.getChart_usl();//规格上限
        Double lsl = spcRetChartInfo.getChart_lsl();//规格下限
        Double ucl = spcRetChartInfo.getChart_ucl();//上控制线
        Double lcl = spcRetChartInfo.getChart_lcl();//下控制线
        Double target = spcRetChartInfo.getChart_target();//目标线
        //Check OOS
        if (("Y").equals(spcRetChartInfo.getChart_spec_chk_flg())) {//规格检查标准
            if (chartValue > usl) {
                spcRetChartInfo.setChart_spec_rlt("U");//检查结果
            } else if (chartValue < lsl) {
                spcRetChartInfo.setChart_spec_rlt("L");
            } else {
                spcRetChartInfo.setChart_spec_rlt("N");
            }
        }
        //Check WE Rule
        String chart_rule1 = spcRetChartInfo.getChart_rule_1_info();//WE Rule与Chart设定关系
        if (chart_rule1 != null && chart_rule1.length() >= 7) {

            SpcRuleCheckItem spcRuleCheckItem = new SpcRuleCheckItem();
            spcRuleCheckItem.setChartValue(chartValue);
            spcRuleCheckItem.setTarget(target);
            spcRuleCheckItem.setUcl(ucl);
            spcRuleCheckItem.setLcl(lcl);
            spcRuleCheckItem.setValues(values);
            String[] rules = new String[chart_rule1.length()];
            for (int i = 0; i < chart_rule1.length(); i++) {
                rules[i] = chart_rule1.charAt(i) + "";
            }
            spcRuleCheckItem.setRules(rules);
            spcRuleCheckItem.setChart_rule1_rlt("");
            droolsUtil.TestRules(spcRuleCheckItem, MAX_SPC_VALUE_CNT);
            System.out.println(spcRuleCheckItem.getChart_rule1_rlt());
            spcRetChartInfo.setChart_rule_1_rlt(spcRuleCheckItem.getChart_rule1_rlt());
        /*
            char rule1 = chart_rule1.charAt(0);//OOC
			char rule2 = chart_rule1.charAt(1);
			char rule3 = chart_rule1.charAt(2);
			char rule4 = chart_rule1.charAt(3);
			char rule5 = chart_rule1.charAt(4);
			char rule6 = chart_rule1.charAt(5);
			char rule7 = chart_rule1.charAt(6);

			String ruleCheckedRlt = "N";
			//八条 rule 这里只写第一条OOC的逻辑

			if ('Y' == rule1) {
				if (chartValue > ucl || chartValue < lcl) {
					//chart_rule1_rlt = getRuleResult( rule1 , true ,chart_rule1_rlt);
					ruleCheckedRlt = "Y";
					//spcRuleRltObj.setChart_total_action_fk("H");
				} else {
					//chart_rule1_rlt = getRuleResult( rule1 , false ,chart_rule1_rlt);
					//spcRuleRltObj.setChart_total_action_fk("N");
				}
			}
			chart_rule1_rlt = chart_rule1_rlt + ruleCheckedRlt;

			//rule 2 :连续8点在同一侧
			int rule2ContinueAboveResult = 0;
			int rule2ContinueBlowResult = 0;
			ruleCheckedRlt = "N";
			if ('Y' == rule2) {
				int counter = 0;
				for (counter = 0; counter < 8; counter++) {
					Double tmpValue = values[MAX_SPC_VALUE_CNT - 1 - counter];
					if(tmpValue == null){
						continue;
					}
					if ( tmpValue> target) {
						rule2ContinueAboveResult++;
					}
					if ( tmpValue < target) {
						rule2ContinueBlowResult++;
					}
					if (rule2ContinueAboveResult > 8 || rule2ContinueBlowResult > 8) {
						ruleCheckedRlt = "Y";
					}
				}
			}

			chart_rule1_rlt = chart_rule1_rlt + ruleCheckedRlt;

			//rule3 : 连续6点持续上升

			int rule3ContinueAscResult = 0;
			int rule3ContinueDescResult = 0;

			ruleCheckedRlt = "N";
			if ('Y' == rule3) {
				for (int i = 0; i < 5; i++) {
					Double firstValue = values[MAX_SPC_VALUE_CNT - 1 - i];
					Double secondValue = values[MAX_SPC_VALUE_CNT - 2 - i];
					if (!isEmpty(firstValue) && !isEmpty(secondValue) && firstValue > secondValue) {
						rule3ContinueAscResult++;
					}
					if (!isEmpty(firstValue) && !isEmpty(secondValue) && firstValue < secondValue) {
						rule3ContinueDescResult++;
					}
				}
				if (rule3ContinueAscResult >= 5 || rule3ContinueDescResult >= 5) {
					ruleCheckedRlt = "Y";
				}

			}

			chart_rule1_rlt = chart_rule1_rlt + ruleCheckedRlt;

			//rule4: 连续14点交互着上线跳动

			int rule4AlternatingUpDownResult = 0;
			ruleCheckedRlt = "N";

			if ('Y' == rule4) {
				for (int i = 0; i < 12; i++) {
					Double valueA = values[MAX_SPC_VALUE_CNT - 1 - i];
					Double valueB = values[MAX_SPC_VALUE_CNT - 2 - i];
					Double valueC = values[MAX_SPC_VALUE_CNT - 3 - i];
					if(valueA == null || valueB == null || valueC == null){
						continue;
					}
					if ((valueA > valueB && valueB < valueC)
							|| (valueA < valueB && valueB > valueC)
							&& isEmpty(valueA)
							&& isEmpty(valueB) && isEmpty(valueC)) {
						rule4AlternatingUpDownResult++;
					}
				}
				if (rule4AlternatingUpDownResult >= 14) {
					ruleCheckedRlt = "Y";
				}

			}

			chart_rule1_rlt = chart_rule1_rlt + ruleCheckedRlt;

			//rule5: 连续三点 有两点落在2σ外

			ruleCheckedRlt = "N";
			int rule5Outof2SigmaCnt = 0;
			if ('Y' == rule5) {
				for (int i = 0; i < 3; i++) {
					Double tmpValue = values[MAX_SPC_VALUE_CNT - 1 - i];
					if(tmpValue == null){
						continue;
					}
					if (tmpValue > (target + ((ucl - target) / 3)*2)
							&& tmpValue < ucl) {
						rule5Outof2SigmaCnt++;
					}
					if (tmpValue < (target - ((target - lcl) / 3)*2)
							&& tmpValue > lcl) {
						rule5Outof2SigmaCnt++;
					}
				}
				if (rule5Outof2SigmaCnt >= 2) {
					ruleCheckedRlt = "Y";
				}
			}
			chart_rule1_rlt = chart_rule1_rlt + ruleCheckedRlt;

			//rule6: 连续5点中有四点落在1σ外

			ruleCheckedRlt = "N";
			int rule6OutOf1SigmaCnt = 0;

			if ('Y' == rule6) {
				for (int i = 0; i < 5; i++) {
					Double tmpValue = values[MAX_SPC_VALUE_CNT - 1 - i];
					if(tmpValue ==null){
						continue;
					}
					if (tmpValue > (target + (ucl - target) / 3)
							&& tmpValue < ucl) {
						rule6OutOf1SigmaCnt++;
					}
					if (tmpValue < (target - (target - lcl) / 3)
							&& tmpValue > lcl) {
						rule6OutOf1SigmaCnt++;
					}
				}
				if (rule6OutOf1SigmaCnt >= 4) {
					ruleCheckedRlt = "Y";
				}
			}

			chart_rule1_rlt = chart_rule1_rlt + ruleCheckedRlt;

			//rule7: 连续15点在中心线上线两侧1σ内

			ruleCheckedRlt = "N";
			int rule7Within1SigmaCnt = 0;
			if ('Y' == rule7) {
				for (int i = 0; i < 15; i++) {
					Double tmpValue = values[MAX_SPC_VALUE_CNT - 1 - i];
					if(tmpValue == null){
						continue;
					}
					if (tmpValue < target + (ucl - target) / 3
							&& tmpValue > target - (target - lcl) / 3) {
						rule7Within1SigmaCnt++;
					}
				}
				if (rule7Within1SigmaCnt >= 15) {
					ruleCheckedRlt = "Y";
				}
			}
			chart_rule1_rlt = chart_rule1_rlt + ruleCheckedRlt;
			spcRetChartInfo.setChart_rule_1_rlt(chart_rule1_rlt);

		*/
        }
        spcRetChartInfoDao.save(spcRetChartInfo);
        return spcRetChartInfo;
    }

    /*计算中位数： NO.02
     * 1.数组排序
     * 2.取中间值 I=(n+1)/2
     * 3.若I为偶数，中位数为(第I个值+第I+1值)/2
     * 4.若I为奇数，中位数为第I个值
     */
    public Double getMedianArray(List<Double> valueList) {
        double temp = 0;
        int median = 0;
        int size = valueList.size();
        Double[] doubleArray = (Double[]) valueList.toArray(new Double[size]);
        sortArray(doubleArray);// 数组排序
        median = (size + 1) / 2; // 中间数
        if (median % 2 == 0) {
            temp = (doubleArray[median] + doubleArray[median + 1]) / 2;
        } else {
            temp = doubleArray[median];
        }
        return temp;
    }

    //NO.02 数组排序
    public void sortArray(Double[] array) {
        for (int i = 0; i < array.length; i++) {
            for (int j = i + 1; j < array.length; j++) {
                if (array[i] > array[j]) {
                    double temp = array[i];
                    array[i] = array[j];
                    array[j] = temp;
                }
            }
        }
    }

    //NO.02 P图 中心线计算
    public Double calucateP(Double sampsize, List<Double> valueList) {
        double avgDouble = 0;
        double total = 0;
        for (int i = 0; i < valueList.size(); i++) {
            total += total + sampsize * valueList.get(i);
        }
        avgDouble = total / sampsize * valueList.size();
        return avgDouble;
    }

    //NO.02 nP图 中心线计算
    public Double calucateNP(Double sampsize, List<Double> valueList) {
        double avgDouble = 0;
        double total = 0;
        for (int i = 0; i < valueList.size(); i++) {
            total += total + sampsize * valueList.get(i);
        }
        avgDouble = total / valueList.size();
        return avgDouble;
    }

    //NO.02 c图 中心线计算
    public Double calucateC(Double sampsize, List<Double> valueList) {
        double avgDouble = 0;
        double total = 0;
        for (int i = 0; i < valueList.size(); i++) {
            total += total + valueList.get(i);
        }
        avgDouble = total / valueList.size();
        return avgDouble;
    }
}
